/*
 * @描述: 
 * @创建者: kilomChou
 * @Date: 2021-04-11 16:57:02
 * @最后编辑: kilomChou
 * @LastEditTime: 2021-10-26 11:24:57
 */
import Food, { FoodType } from "../food/Food"
import SnakeNode from "../snake/SnakeNode"
import Snake from "../snake/Snake"
import World from "./World"
import { Util } from "../../util/Util"
import { IRect, Vec2 } from "../../core/vec2/Vec2"
const [v2] = [Vec2];

/** 区块 */
export default class Chunk implements IRect {

    constructor(
        /**所在世界 */
        readonly world: World,
        rect: IRect) {

        v2.rectAs(this, rect);
        this.foodMap.set(FoodType.normal, new Set());
        this.foodMap.set(FoodType.snake, new Set());
    }

    x: number;
    y: number;
    w: number;
    h: number;

    /** 普通食物的数量 由worldFoodMgr管理 用来控制区块的最大食物容纳数量 */
    normalFoodCount = 0;

    /** 食物映射 */
    readonly foodMap = new Map<FoodType, Set<Food>>();
    /** 蛇节点映射 */
    readonly snakeNodeMap = new Map<Snake, Set<SnakeNode>>();

    /** 添加食物 */
    addFood(food: Food) {
        this.foodMap.get(food.type).add(food);
    }

    /** 移除食物 */
    removeFood(food: Food) {
        this.foodMap.get(food.type).delete(food);
    }

    /** 添加蛇节点 */
    addSnakeNode(node: SnakeNode) {
        let nodes = this.snakeNodeMap.get(node.snake);
        if (!nodes) {
            nodes = new Set<SnakeNode>();
            this.snakeNodeMap.set(node.snake, nodes);
        }
        nodes.add(node);
    }

    /** 移除蛇节点 */
    removeSnakeNode(node: SnakeNode) {
        let nodes = this.snakeNodeMap.get(node.snake);
        if (nodes) {
            nodes.delete(node);
            //该蛇在此区块的节点数为0 将蛇从map中移除
            if (nodes.size == 0) {
                this.snakeNodeMap.delete(node.snake);
            }
        }
    }

    /** 遍历食物 */
    eachFoods(each: (food: Food) => any) {
        this.foodMap.forEach(foodSet => {
            foodSet.forEach(food => {
                each(food);
            })
        })
    }

    /** 获取包含指定蛇集合的蛇节点集合 */
    getSnakeNodeSetInclude(include: Snake[]) {
        let snakeNodeSet = new Set<SnakeNode>();
        include.forEach(snake => {
            let nodeSet = this.snakeNodeMap.get(snake)
            nodeSet && nodeSet.forEach(node => {
                snakeNodeSet.add(node);
            })
        })
        return snakeNodeSet;
    }

    /** 获取不包含指定蛇集合的蛇节点集合 */
    getSnakeNodeSetExclude(exclude: Snake[]) {
        let include = Array.from(this.snakeNodeMap.keys())
        exclude.forEach(snake => Util.arrRemoveItem(include, snake))
        return this.getSnakeNodeSetInclude(include)
    }
}
